<template>
  <div class="article-wrapper p-6 sm:p-8 bg-white dark:bg-gray-800">
    <div ref="articleContentRef" class="article-content" v-viewer v-html="processedHtml" />
    <transition name="fade">
      <div v-if="toast.show" class="copy-toast">{{ toast.message }}</div>
    </transition>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, nextTick, watch } from 'vue'
import hljs from 'highlight.js'
import 'highlight.js/styles/github-dark.css'
import { toClipboard } from '@soerenmartius/vue3-clipboard'

interface Props {
  html: string
}

const props = defineProps<Props>()

const articleContentRef = ref<HTMLElement | null>(null)

// 折叠图标
const foldIconCollapsed = `<svg t="1750157744064" class="icon" viewBox="0 0 1027 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11707" width="16" height="16"><path d="M0 514.24868601C0 231.454916 229.21442201 2.24049401 512.004096 2.24049401 794.77533799 2.24049401 1024 231.454916 1024 514.24868601c0 282.76919401-229.22466201 511.983616-511.995904 511.983616C229.21442201 1026.23230199 0 797.01788 0 514.24868601L0 514.24868601zM960.01075199 514.24868601C960.010752 266.827689 759.416901 66.24202999 512.00409599 66.24202999c-247.42509301 0-448.000512 200.585659-448.00051199 448.00665602 0 247.42918901 200.575419 448.006656 448.000512 448.00665598C759.416901 962.25534199 960.010752 761.677875 960.01075199 514.24868601L960.01075199 514.24868601zM366.873737 542.383885c-7.684035-7.68198701-10.080175-18.21476601-8.312765-28.13519901-1.76741001-9.945008 0.628731-20.467548 8.312765-28.12700699l245.02076-245.002328c12.511132-12.50294 32.73496999-12.50294 45.246102 0 12.494748 12.47222 12.494748 32.75954601 0 45.262486L429.26146199 514.24868599l227.88118501 227.85251301c12.494748 12.517276 12.494748 32.78207401 0 45.315733-12.511132 12.4415-32.73496999 12.4415-45.246102 0L366.873737 542.383885 366.873737 542.383885z" p-id="11708" fill="#cdcdcd"></path></svg>`

const foldIconExpanded = `<svg t="1750157880726" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12890" width="16" height="16"><path d="M512 1024c282.772908 0 512-229.227092 512-512S794.772908 0 512 0 0 229.227092 0 512s229.227092 512 512 512z m0-962.804781c248.972749 0 450.804781 201.832032 450.804781 450.804781S760.972749 962.804781 512 962.804781 61.195219 760.972749 61.195219 512 263.027251 61.195219 512 61.195219z" p-id="12891" fill="#dbdbdb"></path><path d="M483.687012 702.7251a34.82008 34.82008 0 0 0 3.192351 3.681912 35.911394 35.911394 0 0 0 50.241274 0 34.82008 34.82008 0 0 0 3.192351-3.681912l278.305657-278.27506a35.289243 35.289243 0 0 0 0-49.761913 35.289243 35.289243 0 0 0-49.761912 0L512 631.544861 255.143267 374.688127a35.289243 35.289243 0 0 0-49.761912 0 35.289243 35.289243 0 0 0 0 49.761913z" p-id="12892" fill="#dbdbdb"></path></svg>`

// 处理HTML内容，为iframe添加样式
const processedHtml = computed(() => {
  if (!props.html) return ''

  // 使用正则表达式查找iframe标签并添加样式
  return props.html.replace(/<iframe([^>]*)>/gi, (match, attributes) => {
    // 检查是否已经处理过
    if (attributes.includes('data-processed')) {
      return match
    }

    // 添加处理标记和样式
    return `<div class="iframe-container my-4 flex justify-center">
      <div class="iframe-wrapper relative w-full">
        <iframe${attributes} data-processed="true" class="iframe-content w-full h-96 rounded-lg shadow-lg border-2 border-gray-300 dark:border-gray-600" style="display: block; margin: 0; padding: 0;"></iframe>
      </div>
    </div>`
  })
})

// 浮层提示
const toast = ref({ show: false, message: '' })
function showToast(message: string, duration = 1500) {
  toast.value.show = true
  toast.value.message = message
  setTimeout(() => {
    toast.value.show = false
  }, duration)
}

function setupCopyAndFold() {
  if (!articleContentRef.value) return
  const pres = articleContentRef.value.querySelectorAll('pre')

  pres.forEach(pre => {
    if (pre.querySelector('.copy-btn')) return

    const code = pre.querySelector('code')
    if (!code) return

    // 包裹代码内容，方便折叠
    const contentWrapper = document.createElement('div')
    contentWrapper.className = 'code-content-wrapper'
    pre.removeChild(code)
    contentWrapper.appendChild(code)
    pre.appendChild(contentWrapper)

    // 语言标签
    const langMatch = code.className.match(/language-(\w+)/)
    const lang = langMatch ? langMatch[1] : 'code'

    const langSpan = document.createElement('span')
    langSpan.className = 'code-lang'
    langSpan.textContent = lang.toUpperCase()
    pre.appendChild(langSpan)

    // 复制按钮（文字）
    const copyBtn = document.createElement('button')
    copyBtn.className = 'copy-btn'
    copyBtn.type = 'button'
    copyBtn.textContent = '复制代码'
    pre.appendChild(copyBtn)

    // 折叠按钮（图标）
    const foldBtn = document.createElement('button')
    foldBtn.className = 'fold-btn'
    foldBtn.type = 'button'
    foldBtn.title = '折叠/展开代码'
    foldBtn.innerHTML = foldIconExpanded
    pre.appendChild(foldBtn)

    // 初始展开状态
    let expanded = true
    contentWrapper.style.maxHeight = contentWrapper.scrollHeight + 'px'

    // 折叠按钮事件
    foldBtn.addEventListener('click', () => {
      expanded = !expanded
      if (expanded) {
        contentWrapper.style.maxHeight = contentWrapper.scrollHeight + 'px'
        foldBtn.innerHTML = foldIconExpanded
      } else {
        contentWrapper.style.maxHeight = '0'
        foldBtn.innerHTML = foldIconCollapsed
      }
    })

    // 复制事件
    copyBtn.addEventListener('click', async () => {
      const text = code.textContent || ''
      try {
        await toClipboard(text)
        copyBtn.textContent = '复制成功'
        showToast('复制成功')
      } catch (e) {
        copyBtn.textContent = '复制失败'
        showToast('复制失败')
      } finally {
        setTimeout(() => {
          copyBtn.textContent = '复制代码'
        }, 1500)
      }
    })
  })
}

function setupLinks() {
  if (!articleContentRef.value) return
  const anchors = articleContentRef.value.querySelectorAll('a')
  anchors.forEach(a => {
    // 跳过没有 href 的锚点
    if (!a.getAttribute('href')) return
    // 统一样式类
    a.classList.add('article-link')
    // 新窗口打开，防止安全问题
    a.setAttribute('target', '_blank')
    a.setAttribute('rel', 'noopener noreferrer')
  })
}

onMounted(() => {
  nextTick(() => {
    // 为现有的iframe添加样式和全屏按钮
    const iframes = articleContentRef.value?.querySelectorAll('iframe')
    if (iframes) {
      iframes.forEach(iframe => {
        if (!iframe.hasAttribute('data-processed')) {
          // 包装iframe
          const wrapper = document.createElement('div')
          wrapper.className = 'iframe-wrapper relative w-full'

          // 设置iframe样式
          iframe.className =
            'iframe-content w-full h-96 rounded-lg shadow-lg border-2 border-gray-300 dark:border-gray-600'
          iframe.setAttribute('data-processed', 'true')

          // 包装iframe
          iframe.parentNode?.insertBefore(wrapper, iframe)
          wrapper.appendChild(iframe)

          // 添加容器样式
          const container = document.createElement('div')
          container.className = 'iframe-container my-4 flex justify-center'
          wrapper.parentNode?.insertBefore(container, wrapper)
          container.appendChild(wrapper)
        }
      })
    }
    document.querySelectorAll('pre code').forEach(block => {
      hljs.highlightElement(block as HTMLElement)
    })
    setupCopyAndFold()
    setupLinks()
  })
})

watch(
  () => props.html,
  () => {
    nextTick(() => {
      document.querySelectorAll('pre code').forEach(block => {
        hljs.highlightElement(block as HTMLElement)
      })
      setupCopyAndFold()
      setupLinks()
    })
  }
)
</script>

<style>
.article-content {
  font-family: 'Segoe UI', 'Noto Sans', 'Helvetica Neue', sans-serif;
  line-height: 1.75;
  font-size: 14px;
  color: #333;
  word-break: break-word;
  max-width: none;

  /* 响应式字体大小 */
  @media (min-width: 640px) {
    font-size: 16px;
  }

  @media (min-width: 1024px) {
    font-size: 17px;
    line-height: 1.8;
  }

  h1,
  h2,
  h3,
  h4,
  h5,
  h6 {
    font-weight: bold;
    line-height: 1;
    margin-top: 1em;
    margin-bottom: 1em;
  }

  h1 {
    font-size: 1.75em;
    @media (min-width: 640px) {
      font-size: 2em;
    }
  }
  h2 {
    font-size: 1.5em;
    @media (min-width: 640px) {
      font-size: 1.75em;
    }
  }
  h3 {
    font-size: 1.25em;
    border: none;
    @media (min-width: 640px) {
      font-size: 1.5em;
    }
  }
  h4 {
    font-size: 1.125em;
    border: none;
    @media (min-width: 640px) {
      font-size: 1.25em;
    }
  }
  h5 {
    font-size: 1em;
    border: none;
  }
  h6 {
    font-size: 0.875em;
    border: none;
  }

  p {
    margin: 1em 0;
  }

  blockquote {
    margin: 1em 0;
    padding: 1px 1em 1px 1em;
    border-left: 5px solid #13f5f9c5;
    color: #666;
    background-color: rgb(232, 226, 226);
  }

  ul {
    list-style-type: disc;
    padding-left: 1.5rem;
  }

  ol {
    list-style-type: decimal;
    padding-left: 1.5rem;
  }

  code {
    background-color: rgba(173, 176, 179, 0.05);
    color: rgb(64 158 248);
    padding: 0.2em 0.4em;
    margin: 0 2px;
    border-radius: 6px;
    font-size: 0.94em;
    font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
    white-space: break-spaces;
  }

  pre {
    margin-top: 20px;
    margin-bottom: 20px;
    position: relative;
    background-color: #1e1e1e;
    color: #fff;
    padding: 1rem 1rem 1rem 1rem;
    padding-top: 2rem;
    border-radius: 6px;
    overflow-x: auto;
    font-size: 0.95em;
  }

  pre code {
    background-color: transparent !important;
    color: inherit;
    padding: 0;
    font-size: 16px;
  }

  /* 代码块顶部三个红黄绿小点 */
  pre::before {
    content: '';
    position: absolute;
    top: 0.75rem;
    left: 1rem;
    width: 38px;
    height: 10px;
    background-image:
      radial-gradient(circle at center, #ff5f56 5px, transparent 0),
      radial-gradient(circle at center, #ffbd2e 5px, transparent 0),
      radial-gradient(circle at center, #27c93f 5px, transparent 0);
    background-repeat: no-repeat;
    background-position:
      0 0,
      14px 0,
      28px 0;
    background-size: 10px 10px;
  }

  /* 语言标签 */
  pre > .code-lang {
    position: absolute;
    top: 0.5rem;
    right: 6rem;
    color: #dfdcdc;
    font-size: 0.75rem;
    padding: 0.15em 0.5em;
    border-radius: 4px;
    user-select: none;
    text-transform: uppercase;
    font-weight: 600;
    font-family: 'SFMono-Regular', Consolas, monospace;
  }

  /* 复制按钮 */
  pre > .copy-btn {
    position: absolute;
    top: 0.36rem;
    right: 2.1rem;
    border-radius: 4px;
    padding: 0.25em 0.7em;
    font-size: 0.75rem;
    color: #dfdcdc;
    cursor: pointer;
    user-select: none;
    transition: background-color 0.3s;
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    border: none;
  }

  /* 折叠按钮 */
  pre > .fold-btn {
    position: absolute;
    top: 0.65rem;
    right: 0.55rem;
    width: 20px;
    height: 20px;
    padding: 0;
    margin: 0;
    border: none;
    background: transparent;
    cursor: pointer;
    user-select: none;
    display: flex;
    justify-content: center;
    align-items: center;
    transition: background-color 0.3s;
    /* 取消按钮内联默认样式 */
    line-height: 1;
  }
  /* 代码折叠容器 */
  .code-content-wrapper {
    overflow: hidden;
    transition: max-height 0.3s ease;
  }
  pre > .fold-btn svg {
    width: 16px;
    height: 16px;
    display: block; /* 去掉 inline 元素默认的间隙 */
  }

  /* 表格 */
  table {
    border-collapse: collapse;
    width: 100%;
    margin: 1em 0;
  }

  table th,
  table td {
    border: 1px solid #ccc;
    padding: 0.5em;
  }

  img {
    max-width: 100%;
  }

  /* 链接样式 */
  .article-link {
    color: #2563eb; /* tailwind blue-600 */
    text-decoration: underline;
    text-underline-offset: 2px;
    transition: color 0.2s ease;
    word-break: break-all;
  }
  .article-link:hover {
    color: #1d4ed8; /* blue-700 */
  }

  /* 图片描述文字 */
  ::v-deep(.image-caption) {
    min-width: 20%;
    max-width: 80%;
    min-height: 43px;
    display: block;
    padding: 10px;
    margin: 0 auto;
    font-size: 13px;
    color: #999;
    text-align: center;
  }
}

/* 🌙 暗黑模式适配 */
.dark .article-content {
  color: #ccc;

  blockquote {
    background-color: hsl(290, 6%, 20%);
    border-left: 5px solid hsl(281, 75%, 62%);
    color: #c6c5c5;
  }

  code {
    background-color: rgba(255, 255, 255, 0.08);
    color: #ffcb6b;
  }

  pre {
    background-color: #1e1e1e;
    color: #ddd;
  }

  pre > .fold-btn {
    color: #eee;
  }

  table th,
  table td {
    border-color: #555;
  }

  /* 暗黑模式链接样式 */
  .article-link {
    color: #93c5fd; /* blue-300 */
    text-decoration: underline;
  }
  .article-link:hover {
    color: #bfdbfe; /* blue-200 */
  }

  ::v-deep(.image-caption) {
    color: #eeebeb;
  }
}

/* 浮层提示 */
.copy-toast {
  position: fixed;
  bottom: 40px;
  left: 50%;
  transform: translateX(-50%);
  background: #444;
  color: #fff;
  padding: 0.6em 1.2em;
  border-radius: 24px;
  font-size: 0.9rem;
  user-select: none;
  pointer-events: none;
  z-index: 1000;
}

/* 浮层淡入淡出 */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s;
}
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

.iframe-container {
  /* 容器样式 */
  margin: 1rem 0;
  position: relative;
  z-index: 1;
}

.iframe-wrapper {
  /* iframe包装器样式 */
  position: relative;
  display: block;
  width: 100%;
}

.iframe-content {
  /* iframe内容样式 */
  display: block !important;
  width: 100% !important;
  height: 24rem !important; /* h-96 = 24rem */
  max-width: 100% !important;
  margin: 0 !important;
  padding: 0 !important;
  border: 2px solid #d1d5db !important; /* 白天模式：更明显的灰色边框 */
  outline: none !important;
  box-sizing: border-box !important;
  position: relative !important;
  z-index: 1 !important;
  background: transparent !important;
}

/* 暗色模式下的边框 */
.dark .iframe-content {
  border-color: #8ebcc9 !important; /* 暗色模式：深灰色边框 */
}

/* 覆盖可能的弹窗样式 */
.iframe-container * {
  position: relative !important;
  z-index: auto !important;
}

.iframe-container iframe {
  position: relative !important;
  z-index: 1 !important;
}

/* 响应式处理 */
@media (max-width: 768px) {
  .iframe-container {
    margin: 0.75rem 0;
  }

  .iframe-content {
    height: 20rem !important; /* 移动端稍微降低高度 */
  }
}
</style>
